
#include "Path.h"

/* Constructor
 * 
 */
Path::Path() : 
	m_Looped(false)
{
	m_WayPoints.push_back(Ogre::Vector3(0,0,0));
	curWaypoint = m_WayPoints.begin();
}

/* Constructor
 * 
 */
Path::Path(int NumWaypoints, double MinX, double MinY, double MaxX, double MaxY, bool looped) :
	m_Looped(looped)
{
	CreateRandomPath(NumWaypoints, MinX, MinY, MaxX, MaxY);
	curWaypoint = m_WayPoints.begin();
}

/* ~Path()
 * 
 */
Path::~Path()
{}

/* CurrentWayPoint()
 * Return the iterator pointing to the current waypoint
 * in M_WayPoints
 */
Ogre::Vector3 Path::CurrentWayPoint()
{
	return *curWaypoint;
}

/* Finished()
 * Check to see if the curWaypoint pointer
 * is at the end of m_WayPoints list
 */
bool Path::Finished()
{
	return !(curWaypoint != m_WayPoints.end());
}

/* SetNextWaypoint()
 * Move curWaypoint pointer to the next vector
 * in m_WayPoints
 */
void Path::SetNextWaypoint()
{
	if(m_WayPoints.size() > 0)
	{
		if(++curWaypoint == m_WayPoints.end())
		{
			if(m_Looped)
			{
				curWaypoint = m_WayPoints.begin();
			}
		}
	}
}

/* CreateRandomPath(int NumWaypoints, double MinX, double MinY, double MaxX, double MaxY)
 * Create a random path with the constraints passed in
 */
std::list<Ogre::Vector3> Path::CreateRandomPath(int NumWaypoints, double MinX, double MinY, double MaxX, double MaxY)
{
	//Clear all waypoints from the list
	m_WayPoints.clear();

	//Find the middle of the x boundary
	double midX = (MaxX + MinX)/2.0;

	//Find the middle of the y boundary
	double midY = (MaxY + MinY)/2.0;

	//Find the smaller value of the x or y midpoints
	double smaller = std::min(midX, midY);

	//Set the spacing of the waypoints to a ratio of the number of waypoints
	double spaceing = (2 * Ogre::Math::PI) / (double)NumWaypoints;

	//temp variable used to create waypoints
	Ogre::Vector3 temp = Ogre::Vector3::ZERO;		

	//Used to rotate waypoint position
	double RadialDist;		

	for(int i = 0; i < NumWaypoints; i++)
	{
		RadialDist = Ogre::Math::RangeRandom(smaller * .2, smaller);
		temp = Ogre::Vector3(RadialDist, 0.0, 0.0);
		temp.randomDeviant(Ogre::Radian(Ogre::Degree(i*spaceing)), Ogre::Vector3::UNIT_Z);
		temp.x += midX;
		temp.y += midY;
		m_WayPoints.push_back(temp);
	}

	curWaypoint = m_WayPoints.begin();
	return m_WayPoints;
}

/* LoopOn()
 * Set m_Looped = true
 */
void Path::LoopOn()
{
	m_Looped = true;
}

/* LoopOff()
 * Set m_Looped = false
 */
void Path::LoopOff()
{
	m_Looped = false;
}

/* AddWayPoint(Ogre::Vector3 new_point)
 * Add a vector3 at the end of m_WayPoints list
 */
void Path::AddWayPoint(Ogre::Vector3 new_point)
{
	m_WayPoints.push_back(new_point);
}

/* Set(std::list<Ogre::Vector3> new_path)
 * Set m_WayPoints = new_path
 */
void Path::Set(std::list<Ogre::Vector3> new_path)
{
	m_WayPoints = new_path;
	curWaypoint = m_WayPoints.begin();
}

/* Set(Path &path)
 * Set m_WayPoints = path
 */
void Path::Set(Path &path)
{
	m_WayPoints =  path.GetPath();
	curWaypoint = m_WayPoints.begin();
}

/* Clear()
 * Clear m_WayPoints
 */
void Path::Clear()
{
	m_WayPoints.clear();
}

/* GetPath()
 * Return m_WayPoints
 */
std::list<Ogre::Vector3> Path::GetPath()
{
	return m_WayPoints;
}
